package com.fit.utils.se;

import java.io.ByteArrayOutputStream;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.DHParameterSpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 双向加密(可以将加密前的数据解密出来)
 * 非对称加密工具(加密和解密用的 密钥 不是同一个密钥)
 * RSA		加密与解密
 * ElGamal	加密 与解密
 * 
 * 
 * 依赖 jar包 : bouncycastle.jar
 * @author hcl
 */
public class AsymmetricEncryptUtil {
	
	private static Logger log = LoggerFactory.getLogger(AsymmetricEncryptUtil.class);
	
	// //////////////////////////////////////////////////////////
    // RSA加密 与解密
	// 加密示例：A->B 	A提供密钥
	//B向A通信
	// 1、A生成公钥和私钥 -> A将公钥给B(可以让B配置在系统中)
	// 2、B通过公钥加密数据传给A -> A通过私钥解密
	//A向B通信
	// 1、A通过私钥加密数据 -> A通过加密后的数据和私钥生成签名  并将加密后的数据和签名一起传给B
	// 2、B通过公钥验证签名 -> 验证通过后 用公钥对数据进行解密
	//
    // //////////////////////////////////////////////////////////
	
	/**
		RSA加密算法是一种典型的非对称加密算法，它基于大数的因式分解数学难题，它也是应用最广泛的非对称加密算法，于1978年由美国麻省理工学院（MIT）的三位学着：Ron Rivest、Adi Shamir 和 Leonard Adleman 共同提出。 
		它的原理较为简单，我们假设有消息发送方A和消息接收方B，通过下面的几个步骤，我们就可以完成消息的加密传递：
		消息发送方A在本地构建密钥对，公钥和私钥；
		消息发送方A将产生的公钥发送给消息接收方B；
		B向A发送数据时，通过公钥进行加密，A接收到数据后通过私钥进行解密，完成一次通信；
		反之，A向B发送数据时，通过私钥对数据进行加密，B接收到数据后通过公钥进行解密。
		由于公钥是消息发送方A暴露给消息接收方B的，所以这种方式也存在一定的安全隐患，如果公钥在数据传输过程中泄漏，则A通过私钥加密的数据就可能被解密。
		如果要建立更安全的加密消息传递模型，需要消息发送方和消息接收方各构建一套密钥对，并分别将各自的公钥暴露给对方，在进行消息传递时，A通过B的公钥对数据加密，B接收到消息通过B的私钥进行解密，反之，B通过A的公钥进行加密，A接收到消息后通过A的私钥进行解密。
		当然，这种方式可能存在数据传递被模拟的隐患，我们可以通过数字签名等技术进行安全性的进一步提升。由于存在多次的非对称加解密，这种方式带来的效率问题也更加严重。
	 */
	
	
	/**
	 * 加密算法RSA
	 */
    public static final String KEY_ALGORITHM_RSA = "RSA";  
    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";  
    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;  
    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;  
	
	
    
    /**  
     * rsa生成密钥对(公钥和私钥)  
     *   
     * @return  生成的公钥和密钥
     * @throws NoSuchAlgorithmException 
     */  
    public static Keyt rsaKeys() {
    	Keyt keyt = null;
		try {
			KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM_RSA);
			keyPairGen.initialize(1024);
	        KeyPair keyPair = keyPairGen.generateKeyPair();
	        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
	        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 
	        keyt = new Keyt(publicKey.getEncoded(), privateKey.getEncoded());
		} catch (NoSuchAlgorithmException e) {
			log.error("RSA生成公钥和密钥异常", e);
		}
        return keyt;
    }
    
    
    
    /**  
     * rsa 用私钥对信息生成数字签名  
     *   
     * @param data  已加密数据  
     * @param privateKey  私钥
     *   
     * @return  byte[]签名
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws InvalidKeyException 
     * @throws SignatureException 
     */  
    public static byte[] rsaSignByPrivateKey(byte[] data, byte[] privateKey){
    	byte[] sign = null;
		try {
			PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
			PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
	        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
	        signature.initSign(privateK);
	        signature.update(data);
	        sign = signature.sign();
		} catch (GeneralSecurityException e) {
			log.error("RSA 用私钥对信息生成数字签名 异常", e);
		}
        return sign;  
    }  
    
    
    /**  
     * rsa公钥校验数字签名  
     *   
     * @param data 已加密数据  
     * @param publicKey 公钥
     * @param sign  数字签名  
     * 
     * @return  
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws InvalidKeyException 
     * @throws SignatureException 
     *   
     */  
    public static boolean rsaVerifyByPublecKey(byte[] data, byte[] publicKey, byte[] sign){
    	boolean valid = false;
		try {
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);  
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
			PublicKey publicK = keyFactory.generatePublic(keySpec);  
			Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  
			signature.initVerify(publicK);  
			signature.update(data);
			valid = signature.verify(sign);
		} catch (GeneralSecurityException e) {
			log.error("RSA 公钥校验数据签名异常",e);
		}
        return valid;  
    }  
    
    
    /**  
     * rsa 公钥加密  
     *   
     * @param data 源数据  
     * @param publicKey 公钥
     * @return  
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     */  
    public static byte[] rsaEncryptByPublicKey(byte[] data, byte[] publicKey)  {
    	byte[] encryptedData = null;
    	ByteArrayOutputStream out = null;
		try {
			X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
			Key publicK = keyFactory.generatePublic(x509KeySpec);  
	        // 对数据加密  
	        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
	        cipher.init(Cipher.ENCRYPT_MODE, publicK);  
	        int inputLen = data.length;  
	        out = new ByteArrayOutputStream();  
	        int offSet = 0;  
	        byte[] cache;  
	        int i = 0;  
	        // 对数据分段加密  
	        while (inputLen - offSet > 0) {  
	            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {  
	                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);  
	            } else {  
	                cache = cipher.doFinal(data, offSet, inputLen - offSet);  
	            }  
	            out.write(cache, 0, cache.length);  
	            i++;  
	            offSet = i * MAX_ENCRYPT_BLOCK;  
	        }  
	        encryptedData = out.toByteArray();  
		}catch (GeneralSecurityException e) {
			log.error("RSA 公钥加密异常",e);
		}finally{
			IOUtil.close(out);
		}
        return encryptedData;  
    } 
    
    
    
    /**  
     * rsa 私钥加密  
     *   
     * @param data 源数据  
     * @param privateKey 私钥 
     * @return  
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     */  
    public static byte[] rsaEncryptByPrivateKey(byte[] data, byte[] privateKey) {  
        byte[] encryptedData = null;
        ByteArrayOutputStream out = null;
		try {
			PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey); 
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
			Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);  
	        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
	        cipher.init(Cipher.ENCRYPT_MODE, privateK);  
	        int inputLen = data.length;  
	        out = new ByteArrayOutputStream();  
	        int offSet = 0;  
	        byte[] cache;  
	        int i = 0;  
	        // 对数据分段加密  
	        while (inputLen - offSet > 0) {  
	            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {  
	                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);  
	            } else {  
	                cache = cipher.doFinal(data, offSet, inputLen - offSet);  
	            }  
	            out.write(cache, 0, cache.length);  
	            i++;  
	            offSet = i * MAX_ENCRYPT_BLOCK;  
	        }  
	        encryptedData = out.toByteArray();  
		}catch (GeneralSecurityException e) {
			log.error("RSA 私钥加密异常",e);
		}finally{
			IOUtil.close(out);
		}
        return encryptedData;  
    } 
    
    
    
    
    
    /**  
     * rsa 公钥解密  
     *   
     * @param encryptedData  已加密数据  
     * @param publicKey 公钥
     * @return  
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws InvalidKeyException 
     * @throws NoSuchPaddingException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     */  
    public static byte[] rsaDecryptByPublicKey(byte[] encryptedData, byte[] publicKey) {
    	byte[] decryptedData = null;
    	ByteArrayOutputStream out = null;
		try {
			X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);  
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
			Key publicK = keyFactory.generatePublic(x509KeySpec);  
	        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
	        cipher.init(Cipher.DECRYPT_MODE, publicK);  
	        int inputLen = encryptedData.length;  
	        out = new ByteArrayOutputStream();  
	        int offSet = 0;  
	        byte[] cache;  
	        int i = 0;  
	        // 对数据分段解密  
	        while (inputLen - offSet > 0) {  
	            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {  
	                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);  
	            } else {  
	                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);  
	            }  
	            out.write(cache, 0, cache.length);  
	            i++;  
	            offSet = i * MAX_DECRYPT_BLOCK;  
	        }  
	       decryptedData = out.toByteArray();
		}catch (GeneralSecurityException e) {
			log.error("RSA 公钥解密异常",e);
		}finally{
			IOUtil.close(out);
		}
        return decryptedData;  
    } 
    
    
    
    
    
    /**  
     * rsa 私钥解密  
     *   
     * @param encryptedData  已加密数据  
     * @param privateKey  私钥
     * @return  
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     */  
    public static byte[] rsaDecryptByPrivateKey(byte[] encryptedData, byte[] privateKey) {
    	byte[] decryptedData = null;
    	ByteArrayOutputStream out = null;
    	try {
			PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
			Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);  
	        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
	        cipher.init(Cipher.DECRYPT_MODE, privateK);  
	        int inputLen = encryptedData.length;  
	        out = new ByteArrayOutputStream();  
	        int offSet = 0;  
	        byte[] cache;  
	        int i = 0;  
	        // 对数据分段解密  
	        while (inputLen - offSet > 0) {  
	            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {  
	                cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);  
	            } else {  
	                cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);  
	            }  
	            out.write(cache, 0, cache.length);  
	            i++;  
	            offSet = i * MAX_DECRYPT_BLOCK;  
	        }  
	       decryptedData = out.toByteArray();  
		}catch (GeneralSecurityException e) {
			log.error("RSA 私钥解密异常",e);
		}finally{
			IOUtil.close(out);
		}
        return decryptedData;  
    } 

    
	
	
	
	// //////////////////////////////////////////////////////////
    // ElGamal加密 与解密
	// 非对称加密算法ElGamal算法组件 
	// 非对称算法一般是用来传送对称加密算法的密钥来使用的。相对于RSA算法，这个算法只支持私钥加密公钥解密 
	//
	// 这个是一个单向传递数据的过程，这个和RSA不同，RSA的公钥私钥都可以用来做加解密数据的
	// 这里java7不支持ElGamal算法，BouncyCastle支持这个算法
	// 这里的公钥私钥长度几乎一致
	// 这里只有“公钥加密、私钥解密”这一个原则
	//
	// 依赖: bouncycastle.jar
    // //////////////////////////////////////////////////////////
	
    /**
   
	   	使用AES或者ElGamal加密时，当密钥大于128时，代码会抛出java.security.InvalidKeyException: Illegal key size or default parameters
		Illegal key size or default parameters是指密钥长度是受限制的，java运行时环境读到的是受限的policy文件。文件位于${java_home}/jre/lib/security
		这种限制是因为美国对软件出口的控制。
		解决办法：
		去掉这种限制需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.网址如下。
		下载包的readme.txt 有安装说明。就是替换${java_home}/jre/lib/security/ 下面的local_policy.jar和US_export_policy.jar
		jdk5: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#jce_policy-1.5.0-oth-JPR
		jdk6: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
   		jdk7: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
   		
   		在本项目中的file文件加下已经下载好了jce6 和 jce7,只需要解压 替换${java_home}/jre/lib/security 目录中的 local_policy.jar和US_export_policy.jar 即可
   
     */
    
    
    
    
	/**
		一、概述
			1、ElGamal算法和ECC算法基于离散对数问题
			2、这个是一个单向的过程。虽然密钥对构造简单，但是只是乙方向另外一方单向传送数据进行加解密，不能反向操作
			3、这里只有“公钥加密、私钥解密”这个过程
			4、ElGamal不足之处就是 密文会成倍增长
			5、ElGamal和RSA最大不同就是他们构造密钥对的方式不同。还有就是是否为双向加解密
		二、模型分析
			以甲方向乙方发送数据为模型
			1、甲方构造密钥对（公钥+私钥），公布公钥给乙方
			2、这里甲方没法给乙方发送数据了，只有乙方能给甲方传送数据
			3、乙方用公钥对数据进行加密，传送给甲方，甲方用私钥对数据进行解密
	 */
	
	/**
	 * 非对称密钥算法
	 */
    public static final String KEY_ALGORITHM_ELGAMAL = "ElGamal";
	
    /** 
     * 密钥长度，DH算法的默认密钥长度是1024 
     * 密钥长度必须是8的倍数，在160到16384位之间 
     * */  
    private static final int KEY_SIZE=256;  
	
    
    
    
    /** 
     * 初始化密钥对 
     * @return  
     * @throws NoSuchAlgorithmException 
     * @throws InvalidParameterSpecException 
     * @throws InvalidAlgorithmParameterException 
     * */  
    public static Keyt elGamalKeys(){
    	Keyt keyt = null;
		try {
			//加入对BouncyCastle支持  
			Security.addProvider(new BouncyCastleProvider());  
			AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance(KEY_ALGORITHM_ELGAMAL);
			 //初始化参数生成器  
	        apg.init(KEY_SIZE);
	        //生成算法参数  
	        AlgorithmParameters params=apg.generateParameters();  
	        //构建参数材料  
	        DHParameterSpec elParams = params.getParameterSpec(DHParameterSpec.class);  
	        //实例化密钥生成器  
	        KeyPairGenerator kpg=KeyPairGenerator.getInstance(KEY_ALGORITHM_ELGAMAL) ;  
	        //初始化密钥对生成器  
	        kpg.initialize(elParams,new SecureRandom());  
	        KeyPair keyPair=kpg.generateKeyPair();  
	        PublicKey publicKey= keyPair.getPublic();  
	        PrivateKey privateKey= keyPair.getPrivate();  
	        keyt = new Keyt(publicKey.getEncoded(), privateKey.getEncoded());
		} catch (GeneralSecurityException e) {
			log.error("ElGamal生成密钥对异常", e);
		} 
		return keyt;  
    }  
	
    
    /** 
     * 公钥加密 
     * @param data待加密数据 
     * @param key 密钥 
     * @return byte[] 加密数据 
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     * */  
    public static byte[] elGamalEncryptByPublicKey(byte[] data,byte[] key) {  
        byte[] encryptData = null;
        //实例化密钥工厂  
		try {
			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_ELGAMAL);
			//初始化公钥  
	        //密钥材料转换  
	        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);  
	        //产生公钥  
	        PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);  
	        //数据加密
	        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
	        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
	        encryptData = cipher.doFinal(data);
		} catch (GeneralSecurityException e) {
			log.error("ElGamal公钥加密异常",e);
		}
		
        return encryptData;  
    }
    
    
    /** 
     * 私钥解密 
     * @param data 待解密数据 
     * @param key 密钥 
     * @return byte[] 解密数据 
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws NoSuchPaddingException 
     * @throws InvalidKeyException 
     * @throws BadPaddingException 
     * @throws IllegalBlockSizeException 
     * */  
    public static byte[] elGamalDecryptByPrivateKey(byte[] data,byte[] key) {  
    	byte[] decryptData = null;
		 //取得私钥  
        PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(key);  
		try {
			 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_ELGAMAL);
			 //生成私钥  
	        PrivateKey privateKey=keyFactory.generatePrivate(pkcs8KeySpec);  
	        //数据解密  
	        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());  
	        cipher.init(Cipher.DECRYPT_MODE, privateKey);
	        decryptData = cipher.doFinal(data);
		}catch (GeneralSecurityException e) {
			log.error("ElGamal公钥解密异常",e);
		}
        return decryptData;  
    }  
    
    
	// //////////////////////////////////////////////////////////
    // Keyt 对象 用于封装公钥和私钥
    // //////////////////////////////////////////////////////////  
    
    /**
     * 密钥对象(包含了公钥和私钥)
     * @author hcl
     *
     */
    public static class Keyt{
    	private byte[] publicKey = null;
    	private byte[] privateKey = null;
    	
    	/**
    	 * @param publicKey	公钥
    	 * @param privateKey 私钥
    	 */
		public Keyt(byte[] publicKey, byte[] privateKey) {
			this.publicKey = publicKey;
			this.privateKey = privateKey;
		}
		/**
		 * 获取公钥
		 * @return
		 */
		public byte[] getPublicKey() {
			return publicKey;
		}
		/**
		 * 获取私钥
		 * @return
		 */
		public byte[] getPrivateKey() {
			return privateKey;
		}
    }
    
    
	// //////////////////////////////////////////////////////////
    // 加密测试
    // ////////////////////////////////////////////////////////// 
    
    
//    /** 测试
//     * @param args 
//     * @throws Exception  
//     */  
//    public static void main(String[] args) throws Exception {
//    	
//    	//rsa 加密测试
//    	rsaTest();
//    	
//    	//ElGamal 加密解密测试
//    	elGamalTest();
//    }  
//    
//    
//    
//    
//    
//    /**
//     * elGamal加密测试
//     */
//    private static void elGamalTest() throws Exception{
//    	 //初始化密钥  
//        //生成密钥对  
//        Keyt keyt =elGamalKeys(); 
//        //公钥  
//        byte[] publicKey=keyt.getPublicKey();
//        //私钥  
//        byte[] privateKey=keyt.getPrivateKey();
//        System.out.println("公钥：/n"+EncryptUtil.base64Encoder(publicKey));  
//        System.out.println("私钥：/n"+EncryptUtil.base64Encoder(privateKey));  
//          
//        System.out.println("================密钥对构造完毕,甲方将公钥公布给乙方，开始进行加密数据的传输=============");  
//        String str="ElGamal密码交换算法数据";  
//        System.out.println("/n===========甲方向乙方发送加密数据==============");  
//        System.out.println("原文:"+str);  
//          
//        //乙方使用公钥对数据进行加密  
//        byte[] code2=elGamalEncryptByPublicKey(str.getBytes(), publicKey);  
//        System.out.println("===========乙方使用公钥对数据进行加密==============");  
//        System.out.println("加密后的数据："+EncryptUtil.base64Encoder(code2));  
//          
//          
//        //甲方使用私钥对数据进行解密  
//        byte[] decode2=elGamalDecryptByPrivateKey(code2, privateKey);  
//          
//        System.out.println("甲方解密后的数据："+new String(decode2));
//    }
//    
//    
//    
//    
//    
//    
//    
//    
//    
//    /**
//     * rsa加密解密测试
//     * @param args
//     */
//    private static void rsaTest()  throws Exception{
//    	//创建密钥
//    	Keyt keyt = AsymmetricEncrypt.rsaKeys();
//    	
//    	byte[] publicKeyStr = keyt.getPublicKey();
//    	System.out.println("公钥：" + EncryptUtil.base64Encoder(publicKeyStr));
//    	byte[] privateKeyStr = keyt.getPrivateKey();
//    	System.out.println("私钥：" + EncryptUtil.base64Encoder(privateKeyStr));
//    	
//    	
//    	//公钥加密——私钥解密
//    	test1(publicKeyStr,privateKeyStr);
//    	System.out.println("\r\n\r\n");
//    	//私钥加密——公钥解密
//    	test2(publicKeyStr,privateKeyStr);
//	
//	}
//
//
//	/**
//	 * rsa公钥加密——私钥解密
//	 * @throws Exception 
//	 */
//	private static void test1(byte[] publicKey,byte[] privateKey) throws Exception{
//		
//		 System.err.println("公钥加密——私钥解密");  
//	     String source = "这是一行没有任何意义的文字，你看完了等于没看，不是吗？";  
//	     System.out.println("\r加密前文字：\r\n" + source);  
//	     
//	     byte[] encodedData = AsymmetricEncrypt.rsaEncryptByPublicKey(source.getBytes(), publicKey); 
//	     System.out.println("加密后文字：\r\n" + EncryptUtil.base64Encoder(encodedData));  
//	     
//	     byte[] decodedData = AsymmetricEncrypt.rsaDecryptByPrivateKey(encodedData, privateKey);  
//	     System.out.println("解密后文字: \r\n" + new String(decodedData));  
//	}
//
//
//	/**
//	 * rsa 私钥加密——公钥解密(私钥签名——公钥验证签名)
//	 * @throws Exception 
//	 */
//	private static void test2(byte[] publicKey,byte[] privateKey) throws Exception{
//		
//		System.err.println("私钥加密——公钥解密");  
//	    String source = "这是一行测试RSA数字签名的无意义文字";
//	    System.out.println("原文字：\r\n" + source);
//	    //私钥加密操作
//	    byte[] encodedData = AsymmetricEncrypt.rsaEncryptByPrivateKey(source.getBytes(), privateKey);  
//	    System.out.println("加密后：\r\n" + EncryptUtil.base64Encoder(encodedData));
//	    
//	    //私钥通过加密后的数据签名
//	    System.err.println("私钥签名——公钥验证签名");
//	    byte[] sign = AsymmetricEncrypt.rsaSignByPrivateKey(encodedData, privateKey);  
//	    System.err.println("签名:" + EncryptUtil.base64Encoder(sign));  
//	    
//	    
//	    //通过公钥验证签名
//	    boolean status = AsymmetricEncrypt.rsaVerifyByPublecKey(encodedData, publicKey, sign);  
//	    System.err.println("验证结果:" + status);  
//	    if(status){
//	    	//公钥解密操作
//	    	byte[] decodedData = AsymmetricEncrypt.rsaDecryptByPublicKey(encodedData, publicKey);  
//	 	    String target = new String(decodedData);  
//	 	    System.out.println("解密后: \r\n" + target);  
//	    }else{
//	    	System.err.println("签名验证失败！");
//	    }
//	}

	
}
